﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Configuration;
using System.Reflection;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Xml.Linq;
using CoreShop.Library;
using CoreShop.Model;
using CoreShop.Repository;
using Newtonsoft.Json;
using SqlSugar;
using SqlSugar.Extensions;
using Yitter.IdGenerator;
using static CoreShop.Library.GlobalEnumVars;

namespace CoreShop.Services
{
    /// <summary>
    /// 桌位表 接口实现
    /// </summary>
    public class corecmsfoodorderingServices : Repository<corecmsfoodordering>, IcorecmsfoodorderingServices
    {
        public bool InsertAsync(corecmsfoodordering entity)
        {
            return base.Change<corecmsfoodordering>().Insert(entity);
        }

        public override long InsertReturnBigIdentity(corecmsfoodordering entity)
        {
            entity.rowId = base.AsQueryable().Where(p => p.orderId == entity.orderId).Max(p => p.rowId) + 1;
            return base.Change<corecmsfoodordering>().InsertReturnBigIdentity(entity);
        }

        public override bool InsertRange(List<corecmsfoodordering> entity)
        {
            if (entity == null || entity.Count == 0) return false;
            var ordering = entity.First();
            int rowId = base.AsQueryable().Where(p => p.orderId == ordering.orderId).Max(p => p.rowId);
            foreach (var item in entity)
            {
                rowId++;
                item.rowId = rowId;
            }
            return base.InsertRange(entity);
        }

        /// <summary>
        /// 重写异步更新方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool UpdateAsync(corecmsfoodordering entity)
        {
            return base.Change<corecmsfoodordering>().Update(a => new corecmsfoodordering()
            {
                rowId = entity.rowId,
                foodId = entity.foodId,
                foodSpecId = entity.foodSpecId,
                number = entity.number,
                name = entity.name,
                specName = entity.specName,
                quantity = entity.quantity,
                price = entity.price,
                realPrice = entity.realPrice,
                discount = entity.discount,
                amount = entity.amount,
                realAmount = entity.realAmount,
                taskAmount = entity.taskAmount,
                feedAmount = entity.feedAmount,
                sourcePrice = entity.sourcePrice,
                itemType = entity.itemType,
                itemCount = entity.itemCount,
                dataType = entity.dataType,
                taskTitle = entity.taskTitle,
                feedTitle = entity.feedTitle,
                parcel = entity.parcel,
                itemStatus = entity.itemStatus,
                foodTypeId = entity.foodTypeId,

            }, a => a.id == entity.id);
        }
                
        /// <summary>
        /// 重写异步更新方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool UpdateAsync(List<corecmsfoodordering> entity)
        {
            bool returnKey = true;
            foreach (var item in entity)
            {
                returnKey = base.Change<corecmsfoodordering>().Update(a => new corecmsfoodordering()
                {
                    rowId = item.rowId,
                    foodId = item.foodId,
                    foodSpecId = item.foodSpecId,
                    number = item.number,
                    name = item.name,
                    specName = item.specName,
                    quantity = item.quantity,
                    price = item.price,
                    realPrice = item.realPrice,
                    discount = item.discount,
                    amount = item.amount,
                    realAmount = item.realAmount,
                    taskAmount = item.taskAmount,
                    feedAmount = item.feedAmount,
                    sourcePrice = item.sourcePrice,
                    itemType = item.itemType,
                    itemCount = item.itemCount,
                    taskTitle = item.taskTitle,
                    feedTitle = item.feedTitle,
                    parcel = item.parcel,
                    itemStatus = item.itemStatus,
                    foodTypeId = item.foodTypeId,
                }, a => a.id == item.id);
            }
            return returnKey;
        }

        /// <summary>
        /// 重写异步更新方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool SaveOrderingFeed(corecmsfoodordering entity, List<corecmsfoodfeed> foodFeeds)
        {
            var feedIds = foodFeeds.Select(x => x.orderingFeedId).ToList();
            var bl = new corecmsfoodorderingfeedServices().Delete(p => p.detailId == entity.id);
            entity.feedAmount = 0;
            entity.feedTitle = "";
            var orderingFeeds = new List<corecmsfoodorderingfeed>();
            foreach (var foodFeed in foodFeeds)
            {
                if (foodFeed.selectedFlag)
                {
                    var orderingFeed = new corecmsfoodorderingfeed();
                    orderingFeed.detailId = entity.id;
                    orderingFeed.orderId = entity.orderId;
                    orderingFeed.stockId = 0;
                    orderingFeed.feedId = foodFeed.id;
                    orderingFeed.quantity = foodFeed.quantity;
                    orderingFeed.feedPrice = foodFeed.price;
                    orderingFeeds.Add(orderingFeed);

                    entity.feedAmount += foodFeed.quantity * foodFeed.price;
                    if (!string.IsNullOrEmpty(entity.feedTitle)) entity.feedTitle = entity.feedTitle + ",";
                    entity.feedTitle = entity.feedTitle + foodFeed.name;
                }
            }

            if (orderingFeeds.Count > 0)
                bl = new corecmsfoodorderingfeedServices().InsertOrUpdate(orderingFeeds);

            entity.allAmount = entity.realAmount + entity.feedAmount + entity.taskAmount;

            return base.Change<corecmsfoodordering>().Update(a => new corecmsfoodordering()
            {
                feedAmount = entity.feedAmount,
                feedTitle = entity.feedTitle,
                allAmount = entity.allAmount,
            }, a => a.id == entity.id);
        }

        /// <summary>
        /// 保存套菜主商品
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool SaveOrderingSelected(corecmsfoodordering entity)
        {
            var bl = base.Update(entity);
            if (((entity.itemType == (int)GlobalEnumVars.FoodType.PackFood)
                || (entity.itemType == (int)GlobalEnumVars.FoodType.GroupParent)
                || (entity.itemType == (int)GlobalEnumVars.FoodType.TempPack)) && (entity.sourceId > 0))
            {
                return base.Change<corecmsfoodordering>().Update(a => new corecmsfoodordering()
                {
                    quantity = a.foodPackQuantity * entity.quantity,
                    amount = a.foodPackQuantity * entity.quantity * a.price,
                    realAmount = a.foodPackQuantity * entity.quantity * a.realPrice,
                    //taskAmount = a.foodPackQuantity * a.taskAmount,
                    //feedAmount = a.foodPackQuantity * a.feedAmount,
                    allAmount = a.foodPackQuantity * entity.quantity * a.price + a.foodPackQuantity * a.taskAmount + a.foodPackQuantity * a.feedAmount,
                }, a => a.sourceId == entity.sourceId && (a.itemType == (int)GlobalEnumVars.FoodType.PackChild
                || a.itemType == (int)GlobalEnumVars.FoodType.GroupChild));
            }
            return bl;
        }

        /// <summary>
        /// 保存套菜主商品
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool DeleteBySelected(corecmsfoodordering entity)
        {
            var bl = base.DeleteById(entity.id);
            if (((entity.itemType == (int)GlobalEnumVars.FoodType.PackFood) || (entity.itemType == (int)GlobalEnumVars.FoodType.TempPack || entity.itemType == (int)GlobalEnumVars.FoodType.GroupParent)) && (entity.sourceId > 0))
            {
                base.Change<corecmsfoodordering>().Delete(a => a.sourceId == entity.sourceId && a.orderId == entity.orderId);
            }
            return bl;
        }

        /// <summary>
        /// 重写异步更新方法
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="type">0整单做法，1单品做法</param>
        /// <returns></returns>
        public bool SaveOrderingTask(corecmsfoodordering entity, List<corecmsfoodtask> foodTasks, int type)
        {
            var taskIds = foodTasks.Select(x => x.orderingTastId).ToList();
            var bl = false;// new corecmsfoodorderingtaskServices().Delete(p => p.detailId == entity.id);
            entity.taskAmount = 0;
            entity.taskTitle = "";
            var orderingTasks = new List<corecmsfoodorderingtask>();
            List<corecmsfoodordering> foodorderings = new List<corecmsfoodordering>();
            if (type == 0)
            {
                foodorderings = base.AsQueryable().Where(p => p.orderId == entity.orderId && p.itemStatus == (int)OrderingItemStatus.TobePlaced).ToList();
            }
            else
            {
                foodorderings.Add(entity);
            }
            if ((foodorderings == null) || (foodorderings.Count == 0)) return false;
            foreach (var ordering in foodorderings)
            {
                bl = new corecmsfoodorderingtaskServices().Delete(p => p.detailId == ordering.id);
                ordering.taskTitle = "";
                foreach (var foodtask in foodTasks)
                {
                    if (foodtask.selectedFlag)
                    {
                        var orderingTask = new corecmsfoodorderingtask();
                        orderingTask.orderId = ordering.orderId;
                        orderingTask.detailId = ordering.id;
                        orderingTask.tastId = foodtask.id;
                        orderingTask.quantity = foodtask.quantity;
                        orderingTask.taskPrice = foodtask.price;
                        orderingTask.addPriceWay = foodtask.addPriceWay.ObjToInt(0);
                        orderingTasks.Add(orderingTask);

                        if (!string.IsNullOrEmpty(ordering.taskTitle)) ordering.taskTitle = ordering.taskTitle + ",";
                        ordering.taskTitle = ordering.taskTitle + foodtask.name;

                        //计算加价
                        if (orderingTask.addPriceWay == (int)GlobalEnumVars.AddPriceWay.FixAdd)
                            entity.taskAmount += foodtask.price;
                        else if (orderingTask.addPriceWay == (int)GlobalEnumVars.AddPriceWay.QtyAdd)
                        {
                            entity.taskAmount += foodtask.price * entity.quantity;
                        }
                    }
                }
                ordering.allAmount = ordering.realAmount + entity.feedAmount + entity.taskAmount;
            }

            if (orderingTasks.Count > 0)
                bl = new corecmsfoodorderingtaskServices().InsertOrUpdate(orderingTasks);

            return base.UpdateRange(foodorderings);

            //entity.allAmount = entity.realAmount + entity.feedAmount + entity.taskAmount;

            //return base.Change<corecmsfoodordering>().Update(a => new corecmsfoodordering()
            //{
            //    taskAmount = entity.taskAmount,
            //    taskTitle = entity.taskTitle,
            //    allAmount = entity.allAmount,
            //}, a => a.id == entity.id);
        }

        /// <summary>
        /// 重写异步更新方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool SaveOrderingRemark(corecmsfoodordering entity)
        {
            return base.Change<corecmsfoodordering>().Update(a => new corecmsfoodordering()
            {
                remark = entity.remark,
            }, a => a.id == entity.id);
        }

        /// <summary>
        /// 重写删除指定ID的数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteByIdAsync(long id)
        {
            return base.Change<corecmsfoodordering>().DeleteById(id);
        }

        /// <summary>
        /// 重写删除指定ID集合的数据(批量删除)
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public bool DeleteByIdsAsync(int[] ids)
        {
            bool returnKey = true;
            foreach (int id in ids)
            {
                returnKey = base.Change<corecmsfoodordering>().DeleteById(id);
            }
            return returnKey;
        }

        #region 获取缓存的所有数据==========================================================

        /// <summary>
        /// 获取缓存的所有数据
        /// </summary>
        /// <returns></returns>
        public List<corecmsfoodordering> GetCaChe()
        {
            return base.GetList();
        }

        #endregion


        #region 根据套菜ID生成ordering

        /// <summary>
        /// 根据商品类型ID查询类型名称
        /// </summary>
        /// <param name="custoType"></param>
        /// <returns></returns>
        public List<corecmsfoodordering> GetListByFoodPackId(corecmsfoodordering orderingParent)
        {
            var orderingList = new corecmsfoodpackdetailServices().AsQueryable()
                    .LeftJoin<corecmsfoodpack>((d, p) => d.packId == p.id)
                    .LeftJoin<corecmsfood>((d, p, f) => d.foodId == f.id)
                    .LeftJoin<corecmsfoodspec>((d, p, f, s) => d.foodSpecId == s.id)
                    .Where((d, p, f, s) => p.foodId == orderingParent.foodId && d.isDelete == false && s.isDelete == false)
                    .OrderBy(d => d.packId)
                    .Select((d, p, f, s) => new corecmsfoodordering
                    {
                        id = 0,
                        foodPackId = orderingParent.foodId,
                        number = f.number,
                        name = f.name,
                        foodTypeId = f.foodTypeId,
                        rowId = 0,
                        foodId = f.id,
                        foodSpecId = f.foodSpecId,
                        quantity = d.quantity,
                        itemType = (int)GlobalEnumVars.FoodType.PackChild,
                        itemCount = 0,
                        dataType = 1,
                        taskTitle = "",
                        feedTitle = "",
                        parcel = "",
                        itemStatus = 0,
                        taskAmount = 0,
                        feedAmount = 0,
                        packGroupId = p.id,
                        packGroupName = p.name,
                        foodPackQuantity = d.quantity,
                        remark = "",
                        specName = s.specName,
                        price = 0,
                        realPrice = 0,
                        discount = 1,
                        amount = 0,
                        realAmount = 0,
                        sourcePrice = 0,
                        allAmount = 0,
                        setPrice = d.setPrice,
                        isSelectSame = p.isSelectSame,
                        packGroupQuantity = p.quantityEnd,
                        packDetailQuantity = d.quantity,
                        minDiscount = 0,
                    }).ToList();

            int rowId = 1;
            foreach (var item in orderingList)
            {
                item.orderId = orderingParent.orderId;
                item.rowId = rowId;
                rowId++;
            }

            return orderingList;
        }

        #endregion


        #region 根据套菜ID生成ordering

        /// <summary>
        /// 根据商品类型ID查询类型名称
        /// </summary>
        /// <param name="custoType"></param>
        /// <returns></returns>
        public List<corecmsfoodordering> GetListByFoodGroupdetailId(corecmsfoodordering orderingParent)
        {
            var orderingList = new corecmsfooddetailgroupServices().AsQueryable()
                    .LeftJoin<corecmsfoodgroupdetail>((d, g) => d.groupId == g.groupId)
                    .LeftJoin<corecmsfood>((d, g, f) => g.foodId == f.id)
                    .LeftJoin<corecmsfoodspec>((d, g, f, s) => g.foodSpecId == s.id)
                    .Where((d, g, f, s) => d.foodId == orderingParent.foodId && d.isDelete == false)
                    .OrderBy(d => d.groupId)
                    .Select((d, g, f, s) => new corecmsfoodordering
                    {
                        id = 0,
                        foodPackId = orderingParent.foodId,
                        number = f.number,
                        name = f.name,
                        foodTypeId = f.foodTypeId,
                        rowId = 0,
                        foodId = f.id,
                        foodSpecId = f.foodSpecId,
                        quantity = 0,
                        itemType = (int)GlobalEnumVars.FoodType.PackChild,
                        itemCount = 0,
                        dataType = 1,
                        taskTitle = "",
                        feedTitle = "",
                        parcel = "",
                        itemStatus = 0,
                        taskAmount = 0,
                        feedAmount = 0,
                        packGroupId = g.groupId,
                        packGroupName = g.name,
                        foodPackQuantity = 1,
                        remark = "",
                        specName = s.specName,
                        price = s.posPrice,
                        realPrice = s.posPrice,
                        discount = 1,
                        amount = s.posPrice,
                        realAmount = s.posPrice,
                        sourcePrice = 0,
                        allAmount = s.posPrice,
                        setPrice = 0,
                        isSelectSame = d.isSelectSame,
                        packGroupQuantity = d.maxQuantity.Value,
                        packDetailQuantity = d.minQuantity.Value,
                        minDiscount = 0,
                    }).ToList();

            int rowId = 1;
            foreach (var item in orderingList)
            {
                item.orderId = orderingParent.orderId;
                item.rowId = rowId;
                rowId++;
            }

            return orderingList;
        }

        #endregion

        /// <summary>
        /// 根据商品类型ID查询类型名称
        /// </summary>
        /// <param name="custoType"></param>
        /// <returns></returns>
        public corecmsfoodordering CreateByFoodId(long foodSpecId, decimal quantity, long sBillerId)
        {
            var ordering = new corecmsfoodspecServices().AsQueryable()
                    .InnerJoin<corecmsfood>((s, f) => s.foodId == f.id)
                    .Where((s, f) => s.id == foodSpecId)
                    .Select((s, f) => new corecmsfoodordering
                    {
                        rowId = 0,
                        foodId = f.id,
                        foodSpecId = s.id,
                        number = s.number,
                        code = s.code,
                        name = f.name,
                        quantity = quantity,
                        unitName = s.specUnitName,
                        itemType = f.type,
                        itemCount = 1,
                        dataType = 1,
                        taskTitle = "",
                        feedTitle = "",
                        parcel = "",
                        itemStatus = 0,
                        taskAmount = 0,
                        feedAmount = 0,
                        foodPackId = 0,
                        remark = "",
                        sourceId = 0,
                        foodTypeId = f.foodTypeId,
                        createTime = DateTime.Now,
                        specName = s.specName,
                        price = s.posPrice,
                        realPrice = s.posPrice,
                        discount = 1,
                        amount = s.posPrice * quantity,
                        realAmount = s.posPrice * quantity,
                        sourcePrice = s.posPrice,
                        allAmount = s.posPrice * quantity,
                        minDiscount = f.minDiscount,
                        weighType = s.weighType,
                        billerId = sBillerId,
                        foodPackQuantity = 0,
                        unPrint = false,
                        limitBuyQty = 0,
                        minPrice = s.minPrice,
                        maxPrice = s.maxPrice,
                        disItem = s.disItem,
                    }).With(SqlWith.NoLock).ToList().FirstOrDefault();

            if (ordering != null)
            {
                ordering.price = new corecmschgpriceServices().GetChgPrice(ordering.foodSpecId, ordering.price);//调价单
                ordering.realPrice = ordering.price;//调价单的单价
            }

            return ordering;
        }

        /// <summary>
        /// 根据商品类型ID查询类型名称
        /// </summary>
        /// <param name="custoType"></param>
        /// <returns></returns>
        public corecmsfoodordering QueryById(long id)
        {
            return base.Change<corecmsfoodordering>().GetSingle(a => a.id == id);
        }

        /// <summary>
        /// 根据商品类型ID查询类型名称
        /// </summary>
        /// <param name="custoType"></param>
        /// <returns></returns>
        public List<corecmsfoodordering> QueryByOrderId(long id)
        {
            var orderings = base.Change<corecmsfoodordering>().GetList(a => a.orderId == id).OrderBy(p => p.rowId).ToList();
            #region 序号乱就重新生成并保存
            int rowId = 1;
            bool isSave = false;
            foreach (var item in orderings)
            {
                if (item.rowId != rowId)
                {
                    item.rowId = rowId;
                    isSave = true;
                }                
                rowId++;
            }
            if (isSave) base.InsertOrUpdate(orderings);//保存序号
            #endregion
            return orderings;
        }

        /// <summary>
        /// 根据商品类型ID查询类型名称
        /// </summary>
        /// <param name="custoType"></param>
        /// <returns></returns>
        public List<corecmsfoodordering> GetListByOrderId(long id)
        {
            var list = base.AsQueryable()
                    .LeftJoin<sysuser>((p, f) => p.billerId == f.id)
                    .Where((p, f) => p.orderId == id)
                    .Select((p, f) => new corecmsfoodordering
                    {
                        id = p.id,
                        orderId = p.orderId,
                        foodId = p.foodId,
                        foodSpecId = p.foodId,
                        number = p.number,
                        code = p.code,
                        name = p.name,
                        unitName = p.unitName,
                        quantity = p.quantity,
                        itemType = p.itemType,
                        itemCount = p.itemCount,
                        dataType = p.dataType,
                        taskTitle = p.taskTitle,
                        feedTitle = p.feedTitle,
                        parcel = p.parcel,
                        itemStatus = p.itemStatus,
                        taskAmount = p.taskAmount,
                        feedAmount = p.feedAmount,
                        foodPackId = p.foodPackId,
                        foodPackQuantity = p.foodPackQuantity,
                        remark = p.remark,
                        sourceId = 0,
                        foodTypeId = p.foodTypeId,
                        createTime = p.createTime,
                        specName = p.specName,
                        price = p.price,
                        realPrice = p.realPrice,
                        discount = p.discount,
                        amount = p.amount,
                        realAmount = p.realAmount,
                        sourcePrice = p.sourcePrice,
                        allAmount = p.allAmount,
                        minDiscount = p.minDiscount,
                        billerId = p.billerId,
                        billerName = f.nickName,
                    }).ToList();
            return list;
        }               

        #region 根据商品ID生成ordering

        public corecmsprinttaskdetail GePrintTaskItem(corecmsfoodorderingmaster orderMaster, corecmsprintschemedetail printScheme
            , corecmsfoodordering item, long batchId, sysuser billerInfo, corecmsfooddesk deskInfo, int billtypeId, string sBillTitle)
        {
            corecmsprinttaskdetail printtask = new corecmsprinttaskdetail();
            printtask.detailId = item.id;
            printtask.billtypeId = billtypeId;
            printtask.batchId = batchId;
            printtask.orderNo = orderMaster.orderNo;
            printtask.orderNumber = orderMaster.number;
            printtask.quantity = item.quantity;
            printtask.price = item.price;
            printtask.discount = item.discount;
            printtask.realPrice = item.realPrice;
            printtask.amount = item.amount;
            printtask.realAmount = item.realAmount;
            printtask.taskAmount = item.taskAmount;
            printtask.feedAmount = item.feedAmount;
            printtask.allAmount = item.allAmount;
            printtask.foodId = item.foodId;
            printtask.foodSpecId = item.foodSpecId;
            printtask.number = item.number;
            printtask.name = item.name;
            printtask.specName = item.specName;
            printtask.taskTitle = item.taskTitle;
            printtask.feedTitle = item.feedTitle;
            printtask.parcel = item.parcel;
            printtask.foodPackId = item.foodPackId;
            printtask.foodTypeId = item.foodTypeId;
            printtask.person = orderMaster.person;
            printtask.detailRemark = CommFunc.ConvertToString(item.remark);
            printtask.remark = CommFunc.ConvertToString(orderMaster.remark);
            printtask.createTime = DateTime.Now;
            printtask.billerName = "";
            printtask.printSchemeId = printScheme.printSchemeId;
            printtask.templateId = printScheme.templateId;
            printtask.billTitle = sBillTitle;
            printtask.callType = "";
            printtask.printStatus = (int)GlobalEnumVars.PrintStatus.Treat;
            if (item.callType > (int)GlobalEnumVars.CallType.Default)
                printtask.callType = EnumHelper.GetDescByValue<GlobalEnumVars.CallType>(item.callType);
            if (billerInfo != null) printtask.billerName = billerInfo.nickName;

            if (deskInfo != null)
                printtask.deskName = CommFunc.FormatDeskSpellNumber(deskInfo.name, orderMaster.number);

            return printtask;
        }
        #endregion

        #region 退菜处理

        /// <summary>
        /// 订单确认下单billtypeId=4
        /// </summary>
        /// <param name="custoType"></param>
        /// <returns></returns>
        public bool SetFoodRefund(FoodRefundReqModel reqModel, ref string msg)
        {
            var refundList = reqModel.items;
            if ((refundList == null) || (refundList.Count == 0)) return false;
            var corecmsfoodtag = new corecmsfoodtagServices().GetById(reqModel.tagId);

            var refundItem = refundList.FirstOrDefault();
            var refundDetailsPrint = new List<corecmsfoodordering>();
            var refundDetails = new List<corecmsfoodordering>();
            var orderingDetail = QueryByOrderId(refundItem.orderId);
            var orderingMaxId = orderingDetail.Max(p => p.id);
            bool bNewOrderingFlag = false;//是否有添加新的退货行。

            foreach (var refund in refundList)
            {
                var ordering = orderingDetail.Find(p => p.id == refund.id);
                if (ordering == null) continue;
                if (ordering.quantity == refund.quantity)
                {
                    ordering.dataType = (int)GlobalEnumVars.OrderingDataType.Refund;
                    ordering.billerId = reqModel.billerId;
                    ordering.billerName = reqModel.billerName;
                    refundDetails.Add(ordering);
                    refundDetailsPrint.Add(ordering);
                }
                else
                {
                    #region 多数量处理

                    //2、退菜数量小于订单数量，新增一行退菜记录，本行数量减少
                    if (refund.quantity > ordering.quantity)
                    {
                        msg = string.Format("第{0}行【{1}】的退菜数量大于可退数据，保存失败。", ordering.rowId, ordering.name);
                        return false;
                    }
                    //2.1、原记录减退菜数量
                    ordering.quantity = ordering.quantity - refund.quantity;
                    ordering.amount = ordering.quantity * ordering.price;
                    ordering.realAmount = ordering.quantity * ordering.realPrice;
                    ordering.allAmount = ordering.realAmount + ordering.taskAmount + ordering.feedAmount;
                    refundDetails.Add(ordering);

                    //2.2、新增一行退菜记录
                    bNewOrderingFlag = true;
                    string strNewItem = JsonConvert.SerializeObject(ordering);
                    var newOrdering = JsonConvert.DeserializeObject<corecmsfoodordering>(strNewItem);
                    newOrdering.id = 0;
                    newOrdering.sourceId = refund.id;
                    newOrdering.quantity = refund.quantity;
                    newOrdering.dataType = (int)GlobalEnumVars.OrderingDataType.Refund;
                    newOrdering.amount = ordering.price * refund.quantity;
                    newOrdering.realAmount = ordering.realPrice * refund.quantity;
                    newOrdering.taskAmount = 0;
                    newOrdering.feedAmount = 0;
                    newOrdering.allAmount = ordering.realPrice * refund.quantity;
                    newOrdering.createTime = DateTime.Now;
                    newOrdering.billerId = reqModel.billerId;
                    newOrdering.billerName = reqModel.billerName;
                    refundDetails.Add(newOrdering);
                    refundDetailsPrint.Add(newOrdering);
                    #endregion
                }
            }
            var bl = base.InsertOrUpdate(refundDetails);//保存退菜明细
            if (bl)
            {
                refundDetailsPrint.ForEach(p => p.id = p.id == 0 ? p.sourceId : p.id);
                SetFoodPrintTask(refundDetailsPrint);
            }
            var orderingTags = new List<corecmsfoodorderingtag>();
            if (bNewOrderingFlag)
            {
                var newOrdering = base.AsQueryable().Where(p => p.id > orderingMaxId
                && p.dataType == (int)GlobalEnumVars.OrderingDataType.Refund).ToList();
                foreach (var ordering in newOrdering)
                {
                    var orderingTag = new corecmsfoodorderingtag();
                    orderingTag.detailId = ordering.id;
                    orderingTag.orderId = ordering.orderId;
                    orderingTag.tagType = (int)FoodTag.RefundTag;
                    if (corecmsfoodtag != null) orderingTag.tagContent = corecmsfoodtag.content;
                    orderingTags.Add(orderingTag);
                }
            }
            if ((bl) && (orderingTags != null) && (orderingTags.Count > 0))
            {
                new corecmsfoodorderingtagServices().InsertRange(orderingTags);
            }
            return true;
        }
        #endregion

        #region 赠送处理

        /// <summary>
        /// 订单确认下单billtypeId=4
        /// </summary>
        /// <param name="custoType"></param>
        /// <returns></returns>
        public bool SetFoodPresent(FoodRefundReqModel reqModel, ref string msg)
        {
            var presentList = reqModel.items;
            if ((presentList == null) || (presentList.Count == 0)) return false;
            var corecmsfoodtag = new corecmsfoodtagServices().GetById(reqModel.tagId);

            var presentItem = presentList.FirstOrDefault();

            var presentDetails = new List<corecmsfoodordering>();
            var orderingDetail = QueryByOrderId(presentItem.orderId);
            var orderingMaxId = orderingDetail.Max(p => p.id);           

            foreach (var present in presentList)
            {
                var ordering = orderingDetail.Find(p => p.id == present.id);
                if (ordering == null) continue;
                if (ordering.quantity == present.quantity)
                {
                    ordering.dataType = (int)GlobalEnumVars.OrderingDataType.Present;
                    ordering.billerId = reqModel.billerId;
                    ordering.billerName = reqModel.billerName;
                    ordering.sourcePrice = ordering.realPrice;
                    ordering.realPrice = 0;
                    ordering.realAmount = 0;
                    ordering.feedAmount = 0;
                    ordering.taskAmount = 0;
                    ordering.allAmount = 0;
                    presentDetails.Add(ordering);
                }
                else
                {
                    #region 多数量处理

                    //2、赠送数量小于订单数量，新增一行赠送记录，本行数量减少
                    if (present.quantity > ordering.quantity)
                    {
                        msg = string.Format("第{0}行【{1}】的赠送数量大于可赠送数据，保存失败。", ordering.rowId, ordering.name);
                        return false;
                    }
                    //2.1、原记录减赠送菜数量
                    ordering.quantity = ordering.quantity - present.quantity;
                    ordering.amount = ordering.quantity * ordering.price;
                    ordering.realAmount = ordering.quantity * ordering.realPrice;
                    ordering.allAmount = ordering.realAmount + ordering.taskAmount + ordering.feedAmount;
                    presentDetails.Add(ordering);

                    //2.2、新增一行赠送菜记录
                    int rowId = base.AsQueryable().Where(p => p.orderId == presentItem.orderId).Max(p => p.rowId) + 1;
                    string strNewItem = JsonConvert.SerializeObject(ordering);
                    var newOrdering = JsonConvert.DeserializeObject<corecmsfoodordering>(strNewItem);
                    newOrdering.id = 0;
                    newOrdering.rowId = rowId;
                    newOrdering.sourceId = present.id;
                    newOrdering.quantity = present.quantity;
                    newOrdering.dataType = (int)GlobalEnumVars.OrderingDataType.Present;
                    newOrdering.amount = ordering.price * present.quantity;
                    newOrdering.sourcePrice = ordering.realPrice;
                    newOrdering.realPrice = 0;
                    newOrdering.realAmount = 0;
                    newOrdering.taskAmount = 0;
                    newOrdering.feedAmount = 0;
                    newOrdering.allAmount = 0;
                    newOrdering.createTime = DateTime.Now;
                    newOrdering.billerId = reqModel.billerId;
                    newOrdering.billerName = reqModel.billerName;
                    presentDetails.Add(newOrdering);
                    #endregion
                }
            }

            var bl = base.InsertOrUpdate(presentDetails);//保存退菜明细
            return bl;
        }

        #endregion

        #region 退菜生成打印数据
        private void SetFoodPrintTask(List<corecmsfoodordering> refundDetails)
        {
            try
            {
                if (refundDetails == null) return;
                var detail = refundDetails.FirstOrDefault();
                var orderMaster = new corecmsfoodorderingmasterServices().QueryById(detail.orderId);
                if (orderMaster == null) return;
                var deskInfo = new corecmsfooddeskServices().GetById(orderMaster.deskId);
                var printList = new List<corecmsprinttaskdetail>();

                var foodIds = refundDetails.Select(p => p.foodId).ToList();
                var foodprintschemes = new corecmsfoodprintschemeServices().AsQueryable()
                    .Where(p => foodIds.Contains(p.foodId)).ToList();
                var schemeIdsALl = foodprintschemes.Select(p => p.printSchemeId).ToList();
                HashSet<int> schemeIds = new HashSet<int>(schemeIdsALl);

                var printschemeList = new corecmsprintschemedetailServices().AsQueryable()
                    .Where(p => schemeIds.Contains(p.printSchemeId) && p.selectedFlag == true
                    && p.billtypeId == (int)GlobalEnumVars.PrintbillType.Refund).ToList();

                long batchId = 0;
                foreach (var schemeInfo in printschemeList)
                {
                    batchId = (long)YitIdHelper.NextId();
                    foreach (var item in refundDetails)
                    {
                        item.itemStatus = (int)OrderingItemStatus.PreSettled;
                        item.deskName = deskInfo.name;

                        string strNewItem = JsonConvert.SerializeObject(item);
                        var printtask = JsonConvert.DeserializeObject<corecmsprinttaskdetail>(strNewItem);

                        //corecmsprinttaskdetail printtask = new corecmsprinttaskdetail();
                        printtask.id = 0;
                        printtask.detailId = item.id;
                        printtask.batchId = batchId;
                        printtask.billtypeId = (int)GlobalEnumVars.PrintbillType.Refund;
                        printtask.printStatus = (int)GlobalEnumVars.PrintStatus.Treat;
                        printtask.orderNo = orderMaster.orderNo;
                        printtask.orderNumber = orderMaster.number;
                        //printtask.quantity = item.quantity;
                        //printtask.price = item.price;
                        //printtask.discount = item.discount;
                        //printtask.realPrice = item.realPrice;
                        //printtask.amount = item.amount;
                        //printtask.realAmount = item.realAmount;
                        //printtask.taskAmount = item.taskAmount;
                        //printtask.feedAmount = item.feedAmount;
                        //printtask.allAmount = item.allAmount;
                        //printtask.foodId = item.foodId;
                        //printtask.foodSpecId = item.foodSpecId;
                        //printtask.number = item.number;
                        //printtask.name = item.name;
                        //printtask.specName = item.specName;
                        //printtask.taskTitle = item.taskTitle;
                        //printtask.feedTitle = item.feedTitle;
                        //printtask.parcel = item.parcel;
                        //printtask.foodPackId = item.foodPackId;
                        //printtask.foodTypeId = item.foodTypeId;
                        printtask.person = orderMaster.person;
                        printtask.detailRemark = item.remark;
                        printtask.remark = orderMaster.remark;
                        //printtask.billerName = item.billerName;
                        printtask.createTime = DateTime.Now;
                        if (deskInfo != null)
                            printtask.deskName = CommFunc.FormatDeskSpellNumber(deskInfo.name, orderMaster.number);

                        var foodprints = foodprintschemes.Find(p => p.printSchemeId == schemeInfo.printSchemeId && p.foodId == item.foodId);
                        if (foodprints != null)
                        {
                            var printschemeInfo = printschemeList.Find(p => p.printSchemeId == foodprints.printSchemeId);
                            if (printschemeInfo != null)
                            {
                                printtask.printSchemeId = printschemeInfo.printSchemeId;
                                printtask.templateId = printschemeInfo.templateId;
                                printList.Add(printtask);
                            }
                        }
                    }
                }

                var result = new corecmsprinttaskdetailServices().InsertOrUpdate(printList);
            }
            catch (Exception ex)
            {

            }
        }
        #endregion

        #region 转台生成打印数据
        public void SetDeskTransferPrint(corecmsfoodorderingmaster orderMaster, long soureDeskId)
        {
            try
            {
                corecmsfoodordering item = base.AsQueryable().Where(p => p.orderId == orderMaster.orderId).First();
                if (item == null) return;
                var deskSoure = new corecmsfooddeskServices().GetById(soureDeskId);
                var deskInfo = new corecmsfooddeskServices().GetById(orderMaster.deskId);
                item.itemStatus = (int)OrderingItemStatus.PreSettled;

                var printschemeDetailList = new corecmsprintschemedetailServices().AsQueryable()
                      .Where(p => p.selectedFlag == true && p.billtypeId == (int)GlobalEnumVars.PrintbillType.DeskTransfer).ToList();

                if (printschemeDetailList.Count > 0)
                {
                    //暂时只做百事通的转台
                    //var printschemeList = new corecmsprintschemeServices().AsQueryable()
                    //.Where(p => p.sendPrintWay == (int)GlobalEnumVars.SendPrintWay.KDS_Bestone).ToList();

                    foreach (var scheme in printschemeDetailList)
                    {
                        //if (!printschemeList.Select(p => p.id).Contains(scheme.printSchemeId))
                        //    continue;
                        corecmsprinttaskdetail printtask = new corecmsprinttaskdetail();
                        printtask.detailId = item.id;
                        printtask.billtypeId = (int)GlobalEnumVars.PrintbillType.DeskTransfer;
                        printtask.batchId = (long)YitIdHelper.NextId();
                        printtask.orderNo = orderMaster.orderNo;
                        printtask.orderNumber = orderMaster.number;
                        printtask.quantity = item.quantity;
                        printtask.price = item.price;
                        printtask.discount = item.discount;
                        printtask.realPrice = item.realPrice;
                        printtask.amount = item.amount;
                        printtask.realAmount = item.realAmount;
                        printtask.taskAmount = item.taskAmount;
                        printtask.feedAmount = item.feedAmount;
                        printtask.allAmount = item.allAmount;
                        printtask.foodId = item.foodId;
                        printtask.foodSpecId = item.foodSpecId;
                        printtask.number = item.number;
                        printtask.name = item.name;
                        printtask.specName = item.specName;
                        printtask.taskTitle = item.taskTitle;
                        printtask.feedTitle = item.feedTitle;
                        printtask.parcel = item.parcel;
                        printtask.foodPackId = item.foodPackId;
                        printtask.foodTypeId = item.foodTypeId;
                        printtask.person = orderMaster.person;
                        printtask.detailRemark = item.remark;
                        printtask.remark = orderMaster.remark;
                        printtask.createTime = DateTime.Now;
                        printtask.printSchemeId = scheme.printSchemeId;
                        if (deskInfo != null)
                            printtask.deskName = CommFunc.FormatDeskSpellNumber(deskInfo.name, orderMaster.number);
                        if (deskSoure != null)
                            printtask.taskTitle = deskSoure.name;
                        var result = new corecmsprinttaskdetailServices().InsertOrUpdate(printtask);
                    }
                }

            }
            catch
            {

            }
        }
        #endregion

        #region 生成打印数据
        public void SetOrderingToPrint(long bathcId, long orderId, int billtypeId)
        {
            try
            {
                List<corecmsfoodordering> orderings = base.AsQueryable().Where(p => p.batchId == bathcId).ToList();
                if ((orderings == null) || (orderings.Count == 0)) return;
                var orderMaster = new corecmsfoodorderingmasterServices().QueryById(orderId);
                if (orderMaster == null) return;
                var deskInfo = new corecmsfooddeskServices().GetById(orderMaster.deskId);
                List<corecmsprinttaskdetail> printtasks = new List<corecmsprinttaskdetail>();
                foreach (corecmsfoodordering item in orderings)
                {
                    corecmsprinttaskdetail printtask = new corecmsprinttaskdetail();
                    printtask.detailId = item.id;
                    printtask.billtypeId = billtypeId;
                    printtask.batchId = (long)YitIdHelper.NextId();
                    printtask.orderNo = orderMaster.orderNo;
                    printtask.orderNumber = orderMaster.number;
                    printtask.quantity = item.quantity;
                    printtask.price = item.price;
                    printtask.discount = item.discount;
                    printtask.realPrice = item.realPrice;
                    printtask.amount = item.amount;
                    printtask.realAmount = item.realAmount;
                    printtask.taskAmount = item.taskAmount;
                    printtask.feedAmount = item.feedAmount;
                    printtask.allAmount = item.allAmount;
                    printtask.foodId = item.foodId;
                    printtask.foodSpecId = item.foodSpecId;
                    printtask.number = item.number;
                    printtask.name = item.name;
                    printtask.specName = item.specName;
                    printtask.taskTitle = item.taskTitle;
                    printtask.feedTitle = item.feedTitle;
                    printtask.parcel = item.parcel;
                    printtask.foodPackId = item.foodPackId;
                    printtask.foodTypeId = item.foodTypeId;
                    printtask.person = orderMaster.person;
                    printtask.detailRemark = item.remark;
                    printtask.remark = orderMaster.remark;
                    printtask.createTime = DateTime.Now;
                    if (deskInfo != null)
                        printtask.deskName = CommFunc.FormatDeskSpellNumber(deskInfo.name, orderMaster.number);
                    printtasks.Add(printtask);
                }
                var result = new corecmsprinttaskdetailServices().InsertOrUpdate(printtasks);
            }
            catch
            {

            }
        }
        #endregion

        #region 商品分类统计报表
        /// <summary>
        /// 商品分类统计报表
        /// </summary>
        /// <returns></returns>
        public List<ClassDeparts> GetOrderFoodDeparts(long orderId)
        {
            //商品部门
            List<ClassDeparts> foodDeparts = new corecmsfoodorderingServices().AsQueryable()
                .LeftJoin<corecmsfood>((a, f) => a.foodId == f.id)
                .LeftJoin<corecmsdepartment>((a, f, t) => f.departId == t.id)
                .Where((a, f, t) => a.orderId == orderId && a.dataType != (int)GlobalEnumVars.OrderingDataType.Refund
                 && a.dataType != (int)GlobalEnumVars.OrderingDataType.Present)
                .GroupBy((a, f, t) => new { t.id, t.name })
                .Select((a, f, t) => new ClassDeparts
                {
                    dptName = t.name,
                    dptQuantity = SqlFunc.AggregateSum(a.quantity),
                    dptAmount = SqlFunc.AggregateSum(a.amount),
                    dptRealAmount = SqlFunc.AggregateSum(a.allAmount),
                }).With(SqlWith.NoLock).ToList();

            foreach (var item in foodDeparts)
            {
                if (item.dptQuantity != 0) item.dptPrice = Math.Round(item.dptAmount / item.dptQuantity, 2);
            }

            return foodDeparts;
        }
        #endregion


    }
}
